home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
214
/
mandelvroom
/
src
/
palette.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
14KB
|
614 lines
/*
* MandelVroom 2.0
*
* (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
*
* All rights reserved.
*
* Permission is hereby granted to distribute this program's source
* executable, and documentation for non-comercial purposes, so long as the
* copyright notices are not removed from the sources, executable or
* documentation. This program may not be distributed for a profit without
* the express written consent of the author Kevin L. Clague.
*
* This program is not in the public domain.
*
* Fred Fish is expressly granted permission to distribute this program's
* source and executable as part of the "Fred Fish freely redistributable
* Amiga software library."
*
* Permission is expressly granted for this program and it's source to be
* distributed as part of the Amicus Amiga software disks, and the
* First Amiga User Group's Hot Mix disks.
*
* contents: this file contains the functions that open, maintain, operate
* and close the color palette.
*/
#include "mandp.h"
#include <ctype.h>
#define PENLEFT 8
#define PENTOP 15
extern struct Gadget *ContGadget[], *SelGadget[];
UBYTE PaletteOpen;
/*
* Holder for Allocated color potentiometer gadgets.
*/
struct ColorGads {
struct Gadget *RedPot;
struct Gadget *GreenPot;
struct Gadget *BluePot;
};
struct Window *PalWind;
struct ColorGads PalGads;
LONG CurPen;
struct NewWindow NewPal = {
128,0, /* start position */
70,80, /* width, height */
(UBYTE) 0, (UBYTE) -1, /* detail pen, block pen */
NULL, /* IDCMP flags */
/* MandWind flags */
WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH,
(struct Gadget *) NULL, /* first gadget */
(struct Image *) NULL, /* user checkmark */
(UBYTE *) "Colors", /* window title */
(struct Screen *) NULL, /* pointer to screen */
(struct BitMap *) NULL, /* pointer to superbitmap */
80,80,80,80, /* sizing */
CUSTOMSCREEN /* type of screen */
};
/*
* Color Palette Commands
*/
CopyRGBCmd(Msg)
struct IntuiMessage *Msg;
{
struct Gadget *gadget;
register LONG rgb, pen;
/* Need contour selection to complete */
gadget = (struct Gadget *) Msg->IAddress;
if (Msg->Class == GADGETDOWN) {
if (gadget->GadgetID == PALCOPY) { /* Copy command gadget */
SetToPointer();
State = COPYRGBSTATE;
} else {
if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
/* Copy the RGBs from CurPen to NewPen */
pen = GADG_NUM(gadget->GadgetID);
rgb = GetRGB4(vp->ColorMap, CurPen);
SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb);
SaveRGBs(CurPict);
State = IDLESTATE;
}
}
}
}
SpreadRGBCmd(Msg)
struct IntuiMessage *Msg;
{
struct Gadget *gadget;
register LONG pen;
/* Need contour selection to complete */
gadget = (struct Gadget *) Msg->IAddress;
if (Msg->Class == GADGETDOWN) {
if (gadget->GadgetID == PALRANGE) { /* Spread command gadget */
SetToPointer();
State = SPREADRGBSTATE;
} else {
if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
/* Spread the RGBs from CurPen to NewPen */
pen = GADG_NUM(gadget->GadgetID);
ColorRange(CurPen, pen);
SaveRGBs(CurPict);
State = IDLESTATE;
}
}
}
}
ExchangeRGBCmd(Msg)
struct IntuiMessage *Msg;
{
register LONG rgb, rgb2, pen;
struct Gadget *gadget;
/* Need contour selection to complete */
gadget = (struct Gadget *) Msg->IAddress;
if (Msg->Class == GADGETDOWN) {
if (gadget->GadgetID == PALEXCG) { /* Exchange command gadget */
SetWithPointer();
State = XCHGRGBSTATE;
} else {
if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
/* exchange the RGBs in CurPen and NewPen */
pen = GADG_NUM(gadget->GadgetID);
rgb = GetRGB4(vp->ColorMap, CurPen);
rgb2 = GetRGB4(vp->ColorMap, pen);
SetRGB4(vp, CurPen, rgb2 >> 8, rgb2 >> 4, rgb2 );
SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb );
SaveRGBs(CurPict);
State = IDLESTATE;
}
}
}
}
SlideRGBCmd(Msg)
struct IntuiMessage *Msg;
{
struct Gadget *gadget;
gadget = (struct Gadget *) Msg->IAddress;
switch( Msg->Class ) {
case GADGETDOWN: /* Start RGB slide */
StartBarDrag();
State = SLIDERGBSTATE;
break;
case MOUSEMOVE:
ModifyColors(); /* change RGB colors */
break;
case GADGETUP: /* Stop the RGB slide */
ModifyColors();
SaveRGBs(CurPict);
State = IDLESTATE;
break;
}
}
SetCurPen( pen )
int pen;
{
BoxPen( CurPen, NORMALPEN );
CurPen = pen;
SetColorProps(pen);
BoxPen( CurPen, MEDIUMPEN );
SaveRGBs( CurPict );
}
/*
* Blend a range of colors between two pens
*/
ColorRange(first, last)
LONG first, last;
{
LONG i;
register LONG whole, redfraction, greenfraction, bluefraction;
register USHORT rgb;
LONG firstred, firstgreen, firstblue;
LONG lastred, lastgreen, lastblue;
LONG workred, workgreen, workblue;
if (first > last) {
i = first;
first = last;
last = i;
}
/* I need to see a spread of at least two, where there's at least one
* spot between the endpoints, else there's no work to do so I
* might as well just return now.
*/
if (first >= last - 1) return;
rgb = GetRGB4(vp->ColorMap, first);
firstred = (rgb >> 8) & 0xF;
firstgreen = (rgb >> 4) & 0xF;
firstblue = (rgb >> 0) & 0xF;
rgb = GetRGB4(vp->ColorMap, last);
lastred = (rgb >> 8) & 0xF;
lastgreen = (rgb >> 4) & 0xF;
lastblue = (rgb >> 0) & 0xF;
whole = (lastred - firstred) << 16;
redfraction = whole / (last - first);
whole = (lastgreen - firstgreen) << 16;
greenfraction = whole / (last - first);
whole = (lastblue - firstblue) << 16;
bluefraction = whole / (last - first);
for (i = first + 1; i < last; i++)
{
lastred = (redfraction * (i - first) + 0x8000) >> 16;
workred = firstred + lastred;
lastgreen = (greenfraction * (i - first) + 0x8000) >> 16;
workgreen = firstgreen + lastgreen;
lastblue = (bluefraction * (i - first) + 0x8000) >> 16;
workblue = firstblue + lastblue;
SetRGB4(vp, i, workred, workgreen, workblue);
}
} /* ColorRange */
/*
* Modify the colors in the current pen
*/
ModifyColors( )
{
register LONG newred, newgreen, newblue;
newred = ((struct PropInfo *)
PalGads.RedPot->SpecialInfo)->VertPot >> 12;
newgreen = ((struct PropInfo *)
PalGads.GreenPot->SpecialInfo)->VertPot >> 12;
newblue = ((struct PropInfo *)
PalGads.BluePot->SpecialInfo)->VertPot >> 12;
newred = 0xF ^ newred;
newgreen = 0xF ^ newgreen;
newblue = 0xF ^ newblue;
PrintRGB( newred, newgreen, newblue );
SetRGB4(vp, CurPen, newred, newgreen, newblue);
} /* ModifyColors */
PrintRGB( r, g, b )
LONG r,g,b;
{
PrintGad( PalGads.RedPot, r );
PrintGad( PalGads.GreenPot, g );
PrintGad( PalGads.BluePot, b );
}
PrintGad( gadget, Color )
register struct Gadget *gadget;
LONG Color;
{
register struct IntuiText *SaveIntui, *IntuiText = gadget->GadgetText;
char d[4];
SaveIntui = IntuiText;
Color &= 0xf;
sprintf( d, "%x", Color );
d[0] = toupper(d[0]);
IntuiText = IntuiText->NextText;
IntuiText->IText[0] = d[0];
IntuiText = IntuiText->NextText;
IntuiText->IText[0] = d[0];
PrintIText( PalWind->RPort, SaveIntui, gadget->LeftEdge, gadget->TopEdge);
}
/*
* Reflect a pen's new color in the proportional gadget
*/
SetColorProps(pen)
LONG pen;
{
register LONG rgb, red, green, blue;
if (PalWind == NULL)
return;
pen &= Num_vp_Colors - 1;
rgb = GetRGB4(vp->ColorMap, pen);
red = 0xF - ((rgb >> 8) & 0xF);
green = 0xF - ((rgb >> 4) & 0xF);
blue = 0xF - (rgb & 0xF);
red |= (red << 4);
red |= (red << 8);
green |= (green << 4);
green |= (green << 8);
blue |= (blue << 4);
blue |= (blue << 8);
NewModifyProp(PalGads.RedPot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
0L,red,0L,0xfffL,1L);
NewModifyProp(PalGads.GreenPot,PalWind,NULL,FREEVERT|PROPBORDERLESS,
0L,green,0L,0xfffL,1L);
NewModifyProp(PalGads.BluePot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
0L,blue,0L,0xfffL,1L);
} /* SetColorProps */
BoxPen(BoxPen, DrawPen)
LONG BoxPen, DrawPen;
{
register LONG Top, Bot, Left, Right;
register ULONG row, column;
#define PALTOP (PENTOP - 1)
#define PALLEFT (PENLEFT - 1)
#define PENWIDTH (4 << XScale)
#define PENHEIGHT (4 << YScale)
#define PENXPITCH (6 << XScale)
#define PENYPITCH (6 << YScale)
if (PalWind == NULL)
return;
column = BoxPen/8;
row = BoxPen - column*8;
SetAPen(PalWind->RPort, DrawPen);
Left = PALLEFT + PENXPITCH * column;
Top = PALTOP + PENYPITCH * row;
Right = Left + PENWIDTH + 2 + XScale;
Bot = Top + PENHEIGHT + 2 + YScale;
Move(PalWind->RPort, Left, Top);
Draw(PalWind->RPort, Right, Top);
if (DrawPen == HIGHLIGHTPEN) SetAPen(PalWind->RPort, SHADOWPEN);
Draw(PalWind->RPort, Right, Bot);
Draw(PalWind->RPort, Left, Bot);
SetAPen(PalWind->RPort, DrawPen);
Draw(PalWind->RPort, Left, Top + 1);
if (DrawPen) {
row = GetRGB4(vp->ColorMap, BoxPen & (Num_vp_Colors - 1));
PrintRGB( (long) row >> 8, (long) row >> 4, (long) row );
}
}
static LONG WindowWidth;
static LONG WindowHeight;
static LONG BorderLeft;
static struct Border *PensBorder;
/*
* Allocate all the gadgets for the color palette window
*/
struct Gadget *MakePalette()
{
struct Gadget *FirstGadget;
register struct Gadget *NextGadget;
register LONG i,Left,x,y,c = 0;
struct IntuiText *Text, *NextText;
struct PropInfo *PropInfo;
LONG fourx = 4 << XScale;
LONG foury = 4 << YScale;
char *str;
Left = PENLEFT;
FirstGadget = NextGadget =
MakeBool( Left, PENTOP, fourx, foury, 0, PALPEN, GADGIMAGE );
if ( FirstGadget == NULL ) goto error;
i = 1 << (screen->BitMap.Depth);
for (x = 0; x < 6*8 && i > 0; x += 6) {
for (y = 0; y < 6*8 && i > 0; y += 6) {
if (c != 0) {
NextGadget->NextGadget =
MakeBool( Left, (y<<YScale)+PENTOP, fourx, foury, c, PALPEN+c,
GADGIMAGE);
if ((NextGadget = NextGadget->NextGadget) == NULL) goto error;
}
c++;
i--;
}
Left += 6 << XScale;
}
WindowHeight = ((6*8) << YScale) + PENTOP + 6;
c = ((y + 1) << YScale) + 2;
if ( c > WindowHeight ) {
WindowHeight = c + 4;
}
PensBorder = ShadowBorder( BEVELEDUP, 4, 12, Left - 2, c+1);
if (PensBorder == NULL) goto error;
Left += 9;
BorderLeft = Left - 1;
i = -2 * ( XScale ^ 1 );
for (x = y = 0; y < 3; x += 10, y++) {
NextGadget->NextGadget = MakePot( Left + x, 22, fourx,
WindowHeight - 35, PALPOT, y);
NextGadget = NextGadget->NextGadget;
if ( NextGadget == NULL ) goto error;
NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
NextGadget->GadgetText = Text =
ShadowIntui("0", i, WindowHeight - 32 );
if ( Text == NULL ) goto error;
PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
PropInfo->VertBody = 0xfff;
switch (y) {
case 0: PalGads.RedPot = NextGadget;
str = "R";
break;
case 1: PalGads.GreenPot = NextGadget;
str = "G";
break;
case 2: PalGads.BluePot = NextGadget;
str = "B";
break;
}
NextText = Text;
while ( NextText->NextText ) {
NextText = NextText->NextText;
}
NextText->NextText = ShadowIntui( str, i, -11 );
if ( NextText->NextText == NULL ) goto error;
}
Left += 32;
for (c = 0, x = 0; x < 17*3; x += 17) {
NextGadget->NextGadget =
MakeBool( Left, x + 11, 54, 13, 1, PALCNTL+c, NULL);
NextGadget = NextGadget->NextGadget;
if ( NextGadget == NULL) goto error;
switch (c) {
case 0: NextGadget->GadgetText =
ShadowIntui("Copy", 12,3);
break;
case 1: NextGadget->GadgetText =
ShadowIntui("Spread",4,3);
break;
case 2: NextGadget->GadgetText =
ShadowIntui("Exchg", 8,3);
break;
}
c++;
}
WindowWidth = Left + 59;
return(FirstGadget);
error:
FreeBorder( PensBorder );
FreeGadgets( FirstGadget );
return( NULL );
} /* MakePalette */
static struct Gadget *PalGadgets;
/*
* Open the Palette window
*/
OpenPalWind()
{
struct Window *OpenMyWind();
register struct Gadget *gadget;
register struct RastPort *Rp;
LONG fourx = 4 << XScale;
if (CurPict == NULL)
return;
if ( PalWind == NULL ) {
gadget = MakePalette();
if ( gadget == NULL ) {
DispErrMsg("Couldn't get palette gadgets", 0 );
return;
}
PalWind = OpenMyWind( &NewPal, screen, NULL, WindowWidth, WindowHeight);
if ( PalWind != NULL ) {
ModifyIDCMP( PalWind, (long)
PalWind->IDCMPFlags | MOUSEBUTTONS | MOUSEMOVE );
Rp = PalWind->RPort;
SetAPen( Rp, NORMALPEN );
RectFill( Rp, LEFTMARG, TOPMARG,
WindowWidth,WindowHeight);
BorderWindow( PalWind );
PalGadgets = gadget;
AddGList( PalWind, gadget, -1, -1);
RefreshGadgets( gadget, PalWind, NULL );
DrawBorder( Rp, PensBorder, 0L, 0L );
FreeBorder( PensBorder );
CurPen &= Num_vp_Colors - 1;
BoxPen( CurPen, MEDIUMPEN );
SetColorProps( CurPen );
}
} else {
WindowToFront( PalWind );
}
PaletteOpen = 1;
} /* OpenPalWind */
/*
* Close the Palette window
*/
ClosePalWind()
{
if (PalWind != NULL) {
NewPal.LeftEdge = PalWind->LeftEdge;
NewPal.TopEdge = PalWind->TopEdge;
CloseMyWind(PalWind,PalGadgets);
PalGadgets = NULL;
}
PalWind = NULL;
} /* ClosePalWind */